#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <functional>

//////////////////////////////////////////////////////////////////////////////////
// 子进程退出时core dump
int main()
{
    if (fork() == 0)
    {
        sleep(1);
        int a = 10;
        a /= 0;
        exit(0);
    }

    int status = 0;
    waitpid(-1, &status, 0);
    std::cout << "exit signal: " << (status & 0x7F) << std::endl;
    std::cout << "core dump: " << ((status >> 7) & 1) << std::endl;

    return 0;
}

//////////////////////////////////////////////////////////////////////////////////
// using func_t = std::function<void()>;
// std::vector<func_t> gfuncs;
// int gcount = 0;

// void Handler(int signo)
// {
//     for (auto &f : gfuncs)
//     {
//         f();
//     }
//     int n = alarm(1);//设置反复的闹钟
//     std::cout << "gcount = " << gcount << " n = " << n << std::endl;
// }

// // 设置重复闹钟，模拟操作系统的原理
// int main()
// {
//     // push_back()里面的参数是Lambda表达式，即匿名函数，[]代表捕获列表，[]里面的内容表示要捕获的外部变量
//     gfuncs.push_back([]()
//                      { std::cout << "我是一个下载任务" << std::endl; });
//     gfuncs.push_back([]()
//                      { std::cout << "我是一个日志任务" << std::endl; });
//     gfuncs.push_back([]()
//                      { std::cout << "我是一个sql任务" << std::endl; });

//     alarm(1); // 一次性闹钟，响完就关闭了
//     signal(SIGALRM, Handler);

//     while (true)
//     {
//         pause();//使进程被挂起，直到有个信号来唤醒它
//         std::cout << "i am awaked" << std::endl;
//         gcount++;
//     }

//     return 0;
// }

//////////////////////////////////////////////////////////////////////////////////
// void Handler(int signo)
// {
//     std::cout << "捕捉到一个信号, signo: " << signo << std::endl;
//     //这里只是捕捉了信号，没有执行退出进程的操作
// }
// //野指针异常
// int main()
// {
//     signal(SIGSEGV, Handler);
//     int* p = nullptr;
//     *p = 100;
//     while(true) std::cout << "a" << std::endl;
//     return 0;
// }

//////////////////////////////////////////////////////////////////////////////////
// void Handler(int signo)
// {
//     std::cout << "捕捉到一个信号, signo: " << signo << std::endl;
//     //这里只是捕捉了信号，没有执行退出进程的操作
// }
// //除0异常
// int main()
// {
//     signal(SIGFPE, Handler);
//     int a = 10;
//     a = a / 0;
//     while(true) std::cout << "a" << std::endl;
//     return 0;
// }

//////////////////////////////////////////////////////////////////////////////////
// alarm软件条件产生信号
// IO流多的：IO流影响计算效率
//  int main()
//  {
//      alarm(1);
//      int num = 0;
//      while(true)
//      {
//          // std::cout << "num = " << num << std::endl;
//          // num++;
//          printf("num = %d\n", num++);
//      }
//      return 0;
//  }

// IO流少的：效率比较高
//  int num = 0;
//  void Handler(int signo)
//  {
//      std::cout << "num = " << num << std::endl;
//      exit(1);
//  }
//  int main()
//  {
//      alarm(1);
//      signal(SIGALRM, Handler);
//      while(1)
//      {
//          num++;
//      }
//      return 0;
//  }

//////////////////////////////////////////////////////////////////////////////////
// void Handler(int signo)
// {
//     std::cout << "捕捉到一个信号, signo: " << signo << std::endl;
// }

// abort:给调用进程发送SIGABRT信号导致进程异常终止
// int main()
// {
//     int number = 0;
//     signal(SIGABRT, Handler);
//     while (true)
//     {
//         std::cout << "still alive!" << std::endl;
//         number++;
//         sleep(1);
//         if (number == 10)
//         {
//             abort();
//         }
//     }
//     return 0;
// }

//////////////////////////////////////////////////////////////////////////////////
// raise：自己给自己发送指定的信号
//  int main()
//  {
//      int number = 0;
//      while(true)
//      {
//          std::cout << "still alive!" << std::endl;
//          number++;
//          sleep(2);
//          if(number == 10)
//          {
//              raise(SIGKILL);
//          }
//      }
//      return 0;
//  }

//////////////////////////////////////////////////////////////////////////////////
// void Handler(int signo)
// {
//     std::cout << "i am signo " << signo << std::endl;
// }

// signal函数：修改指定信号的默认行为
//  int main()
//  {
//      std::cout << "i am a process, pid: " << getpid() << std::endl;
//      signal(SIGKILL, Handler);
//      while(true)
//      {
//          std::cout << "i am a process." << std::endl;
//          sleep(2);
//      }
//      return 0;
//  }

//////////////////////////////////////////////////////////////////////////////////
// void Usage(std::string proc)
// {
//     std::cout << "Usage error: " << proc << " signal_number pid" << std::endl;
// }

// //实现自己的kill命令./mykill 9 processid
// int main(int argc, char* argv[])
// {
//     if(argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }
//     pid_t pid = std::stoi(argv[2]);
//     int signo = std::stoi(argv[1]);
//     kill(pid, signo);
//     return 0;
// }